﻿using Conqueror.WP.Matchmaking;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Conqueror.WP.ViewModel.Matchmaking
{
    public class MatchmakingViewModel : ViewModel
    {
        private ObservableCollection<MapViewModel> maps = new ObservableCollection<MapViewModel>();

        public ObservableCollection<MapViewModel> Maps
        {
            get { return maps; }
        }

        private MapViewModel selectedMap;

        public MapViewModel SelectedMap
        {
            get { return selectedMap; }
            set
            {
                if (selectedMap != value)
                {
                    selectedMap = value;
                    Notify("SelectedMap");
                }
            }
        }

        private int minPlayers;
        public int MinPlayers
        {
            get { return minPlayers; }
            set
            {
                if (minPlayers != value)
                {
                    minPlayers = value;
                    Notify("MinPlayers");
                }
            }
        }

        private int maxPlayers;
        public int MaxPlayers
        {
            get { return maxPlayers; }
            set
            {
                if (maxPlayers != value)
                {
                    maxPlayers = value;
                    Notify("MaxPlayers");
                }
            }
        }

        private int selectedInitialTroops;
        private ObservableCollection<API.InitialTroops> InitialTroops = new ObservableCollection<API.InitialTroops>() {
            API.InitialTroops.Unknown,
            API.InitialTroops.Automatic,
            API.InitialTroops.Manual
        };

        public int SelectedInitialTroops
        {
            get { return selectedInitialTroops; }
            set
            {
                if (selectedInitialTroops != value)
                {
                    selectedInitialTroops = value;
                    Notify("SelectedInitialTroops");
                }
            }
        }

        private int selectedPlayOrder;
        private ObservableCollection<API.PlayOrder> PlayOrder = new ObservableCollection<API.PlayOrder>() {
            API.PlayOrder.Unknown,
            API.PlayOrder.Sequential,
            API.PlayOrder.Freestyle
        };

        public int SelectedPlayOrder
        {
            get { return selectedPlayOrder; }
            set
            {
                if (selectedPlayOrder != value)
                {
                    selectedPlayOrder = value;
                    Notify("SelectedPlayOrder");
                }
            }
        }

        private int selectedGameType;
        private ObservableCollection<API.GameType> GameType = new ObservableCollection<API.GameType>() {
            API.GameType.Unknown,
            API.GameType.Standard,
            API.GameType.Terminator,
            API.GameType.Assassin,
            API.GameType.Polymorphic,
            API.GameType.Doubles,
            API.GameType.Triples,
            API.GameType.Quadruples
        };

        public int SelectedGameType
        {
            get { return selectedGameType; }
            set
            {
                if (selectedGameType != value)
                {
                    selectedGameType = value;
                    Notify("SelectedGameType");
                }
            }
        }

        private int selectedSpoils;
        private ObservableCollection<API.Spoils> Spoils = new ObservableCollection<API.Spoils>() {
            API.Spoils.Unknown,
            API.Spoils.Escalating,
            API.Spoils.FlatRate,
            API.Spoils.Nuclear,
            API.Spoils.Zombie,
            API.Spoils.NoSpoils
        };

        public int SelectedSpoils
        {
            get { return selectedSpoils; }
            set
            {
                if (selectedSpoils != value)
                {
                    selectedSpoils = value;
                    Notify("SelectedSpoils");
                }
            }
        }

        private int selectedFortifications;
        private ObservableCollection<API.Fortifications> Fortifications = new ObservableCollection<API.Fortifications>()
        {
            API.Fortifications.Unknown,
            API.Fortifications.Chained,
            API.Fortifications.Adjacent,
            API.Fortifications.Unlimited,
            API.Fortifications.Parachute,
            API.Fortifications.None
        };

        public int SelectedFortifications
        {
            get { return selectedFortifications; }
            set
            {
                if (selectedFortifications != value)
                {
                    selectedFortifications = value;
                    Notify("SelectedFortifications");
                }
            }
        }

        private int selectedFogOfWar;
        public int SelectedFogOfWar
        {
            get { return selectedFogOfWar; }
            set
            {
                if (selectedFogOfWar != value)
                {
                    selectedFogOfWar = value;
                    Notify("SelectedFogOfWar");
                }
            }
        }

        private int selectedTrenchWarfare;
        public int SelectedTrenchWarfare
        {
            get { return selectedTrenchWarfare; }
            set
            {
                if (selectedTrenchWarfare != value)
                {
                    selectedTrenchWarfare = value;
                    Notify("SelectedTrenchWarfare");
                }
            }
        }

        private static MatchmakingViewModel instance;
        public static MatchmakingViewModel Instance { get { return instance; } }

        public MatchmakingViewModel()
        {
            instance = this;
            DownloadMaps();
        }

        private async void DownloadMaps()
        {
            List<API.Map> maps = await API.Map.GetMapAsync();
            foreach (var map in maps)
            {
                if (map.Status != API.MapStatus.Closed)
                    this.maps.Add(new MapViewModel(map));
            }
        }

        public MatchmakingParameters CreateMatchmakingParams()
        {
            MatchmakingParameters p = new MatchmakingParameters();

            p.Map = selectedMap.Name;
            p.MaxPlayers = MaxPlayers;
            if (p.MaxPlayers < 2) p.MaxPlayers = 2;
            p.MinPlayers = MinPlayers;
            if (p.MinPlayers < 2) p.MinPlayers = 2;

            p.InitialTroops = InitialTroops[selectedInitialTroops];
            p.PlayOrder = PlayOrder[selectedPlayOrder];
            p.GameType = GameType[selectedGameType];
            p.Spoils = Spoils[selectedSpoils];
            p.Fortifications = Fortifications[selectedFortifications];
            switch(selectedFogOfWar)
            {
                default:
                case 0: p.FogOfWar = null; break;
                case 1: p.FogOfWar = true; break;
                case 2: p.FogOfWar = false; break;
            }
            switch (selectedTrenchWarfare)
            {
                default:
                case 0: p.TrenchWarfare = null; break;
                case 1: p.TrenchWarfare = true; break;
                case 2: p.TrenchWarfare = false; break;
            }

            return p;
        }
    }
}
